Internal wire connection of keypad
Matrix Keypad Interface Logic
There are two ways by which PIC18F can perform key press detection :-
Initial setup:
Step 1:
Step 2:
Step 3
Step 4:
Steps to read a key from the keypad
Applications:
/* Name : main.c
* Purpose : Source code for KEYPAD Interfacing with PIC18F4550.
* Author : Gemicates
* Date : 2017-07-07
* Website : www.gemicates.org
* Revision : None
*/
#include <htc.h> //Header file for PIC18F4550
#define _XTAL_FREQ 12000000 //12MHZ
/**********CONFIGURATION BITS SETTING**********/
#pragma config FOSC = HSPLL_HS // Using 20 MHz crystal with PLL
#pragma config PLLDIV = 5 // Divide by 5 to provide the 96 MHz PLL with 4 MHz input
#pragma config PBADEN = OFF
#pragma config CPUDIV = OSC1_PLL2 // Divide 96 MHz PLL output by 2 to get 48 MHz system clock
#pragma config FCMEN = OFF // Disable Fail-Safe Clock Monitor
#pragma config IESO = OFF // Disable Oscillator Switchover mode
#pragma config PWRT = OFF // Disable Power-up timer
#pragma config BOR = OFF // Disable Brown-out reset
#pragma config WDT = OFF // Disable Watchdog timer
#pragma config MCLRE = ON // Enable MCLR Enable
#pragma config LVP = OFF // Disable low voltage ICSP
#pragma config ICPRT = OFF // Disable dedicated programming port (only on 44-pin devices)
#pragma config CP0 = OFF // Disable Code Protection Bit
/************************************************/
#define RS PORTCbits.RC0 //To assign single bit(RC0) of PORTC as output
#define RW PORTCbits.RC1 //To assign single bit(RC1) of PORTC as output
#define EN PORTCbits.RC2 //To assign single bit(RC2) of PORTC as output
#define R1 PORTBbits.RB0 //To assign single bit(RB0) of PORTB as output
#define R2 PORTBbits.RB1 //To assign single bit(RB1) of PORTB as output
#define R3 PORTBbits.RB2 //To assign single bit(RB2) of PORTB as output
#define R4 PORTBbits.RB3 //To assign single bit(RB3) of PORTB as output
#define C1 PORTBbits.RB4 //To assign single bit(RC1) of PORTB as input
#define C2 PORTBbits.RB5 //To assign single bit(RC2) of PORTB as input
#define C3 PORTBbits.RB6 //To assign single bit(RC3) of PORTB as input
#define Lcd_port PORTD //To assign Lcd data pins as PORTD
void lcdcmd_address(unsigned char cmd);
void lcddata(unsigned char send_data);
void lcd_string(unsigned char str[10]);
void lcd_data_string(unsigned char *str);
void check_column_one();
void check_column_two();
void check_column_three();
void output(int key);
void main() // main function
{
TRISD=0x00; //PORTD as a output
TRISC=0x00; //PORTC as a input
TRISB=0xF0; //Upper bits as output and Lower bits as input
PORTD=0x00; //PORTD as a output
PORTC=0x00; //PORTC as a output
PORTB=0xF0; //Upper bits as output and Lower bits as input
lcdcmd_address(0x38); // for using 8-bit 2 row mode and 5x7 Dots of LCD
lcdcmd_address(0x0E); // turn display ON for cursor blinking
lcdcmd_address(0x01); // clear screen
lcdcmd_address(0x06); // display ON
__delay_ms(60);
lcdcmd_address(0x86); // bring cursor to position 6 of ROW 1
lcddata('H'); // display H on LCD
lcdcmd_address(0x87); // bring cursor to position 7 of ROW 1
lcddata('I'); // display I on LCD
lcddata('!'); // display ! on LCD
__delay_ms(60);
lcdcmd_address(0xC3); // bring cursor to position 3 of ROW 2
lcd_string("**GUYS**"); // display **GUYS** on LCD
__delay_ms(60);
lcdcmd_address(0x01); // clear screen
lcdcmd_address(0x83); // bring cursor to position 3 of ROW 1
lcd_string("WELCOME TO"); // display WELCOME TO on LCD
__delay_ms(60);
lcdcmd_address(0xC3); // bring cursor to position 3 of ROW 2
lcd_string("GEMICATES"); // display GEMICATES on LCD
lcdcmd_address(0x01); // clear screen
lcdcmd_address(0x0C); // Display On cursor Off
C1=C2=C3=1; // Initialiy set the column as high // The output of all the columns will be high
while(1)
{
R1=R2=R3=R4=0; // Initialiy set the column as low // made all the rows zero
if(C1==0)
check_column_one(); // check pressed key is a column one?
else if(C2==0)
check_column_two(); // check pressed key is a column two?
else if(C3==0)
check_column_three(); // check pressed key is a column three?
}
}
void lcdcmd_address(unsigned char cmd) // Function to send command to LCD
{
Lcd_port = cmd;
PORTCbits.RC0= 0; // Register select (RS) in command mode
PORTCbits.RC1= 0; // Read/Write(RW) in Write operation
PORTCbits.RC2= 1; // Enable(RC2) bit
__delay_ms(60);
PORTCbits.RC2= 0; //Disable(RC2) bit
}
void lcddata(unsigned char send_data) // Function to send data to LCD
{
Lcd_port = send_data;
PORTCbits.RC0= 1; // Register select(RS) in Data mode
PORTCbits.RC1=0; // Read/Write(RW) in Write operation
PORTCbits.RC2=1; // Enable(RC2) bit
__delay_ms(60);
PORTCbits.RC2=0; // Enable(RC2) bit
}
void lcd_string(unsigned char str[10]) // Funtion to Initialize LCD
{
lcd_data_string(str);
}
void lcd_data_string(unsigned char *str) // Function to send string on LCD
{
int i=0;
while(str[i]!='\0')
{
lcddata(str[i]);
i++;
__delay_ms(60);
}
}
void check_column_one() // Detecting column one?
{
R1=R2=R3=R4=1; // After detecting column All rows set to high
R1=0;
if((R1==0)&&(C1==0))
output(1);
R1=1;
__delay_ms(60);
R2=0;
if((R2==0)&&(C1==0))
output(4);
R2=1;
__delay_ms(60);
R3=0;
if((R3==0)&&(C1==0))
output(7);
R3=1;
__delay_ms(60);
R4=0;
if((R4==0)&&(C1==0))
output(10);
R4=1;
}
void check_column_two() // Detecting column two?
{
R1=R2=R3=R4=1; // After detecting column All rows set to high
R1=0;
if((R1==0)&&(C2==0))
output(2);
R1=1;
__delay_ms(60);
R2=0;
if((R2==0)&&(C2==0))
output(5);
R2=1;
__delay_ms(60);
R3=0;
if((R3==0)&&(C2==0))
output(8);
R3=1;
__delay_ms(60);
R4=0;
if((R4==0)&&(C2==0))
output(11);
R4=1;
}
void check_column_three() // Detecting column three?
{
R1=R2=R3=R4=1; // After detecting column All rows set to high
R1=0;
if((R1==0)&&(C3==0))
output(3);
R1=1;
__delay_ms(60);
R2=0;
if((R2==0)&&(C3==0))
output(6);
R2=1;
__delay_ms(60);
R3=0;
if((R3==0)&&(C3==0))
output(9);
R3=1;
__delay_ms(60);
R4=0;
if((R4==0)&&(C3==0))
output(12);
R4=1;
}
void output(int key)
{
lcdcmd_address(0x01); // clear screen
lcdcmd_address(0x86); // bring cursor to position 3 of ROW 1
switch(key)
{
case 1:
lcd_string("ONE");
break;
case 2:
lcd_string("TWO");
break;
case 3:
lcd_string("THREE");
break;
case 4:
lcd_string("FOUR");
break;
case 5:
lcd_string("FIVE");
break;
case 6:
lcd_string("SIX");
break;
case 7:
lcd_string("SEVEN");
break;
case 8:
lcd_string("EIGHT");
break;
case 9:
lcd_string("NINE");
break;
case 10:
lcd_string("TEN");
break;
case 11:
lcd_string("ELEVEN");
break;
case 12:
lcd_string("TWELVE");
break;
}
}